package com.example.wxback.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.example.wxback.model.ActivationCodePo;
import com.example.wxback.model.UserInfo;
import com.example.wxback.model.UserInfoDto;
import com.example.wxback.redis.JedisDao;
import com.example.wxback.service.ActivationCodeService;
import com.example.wxback.service.WxUserService;
import com.example.wxback.session.SessionUserInfo;
import com.example.wxback.util.*;
import com.example.wxback.util.constants.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/wx/user")
public class WxUserController {

    @Autowired
    WxUserService wxUserService;

    @Autowired
    ActivationCodeService activationCodeService;

    @Autowired
    private JedisDao jedisDao;

    private String KEY = "USER_TOKEN";

    private Map<Integer, String> UserLogin = new HashMap<>();

    @GetMapping("/users")
    public JSONObject getUser(@Param("pageNum") int pageNum,
                              @Param("pageRow") int pageRow,
                              @Param("phone") String phone,
                              @Param("memberType") Integer memberType,
                              @Param("expiredType") String expiredType,
                              HttpServletRequest request) {
        SessionUserInfo sessionUserInfo = (SessionUserInfo) request.getAttribute("users");
        if (sessionUserInfo == null) {
            return CommonUtil.errorJson("管理员不存在");
        }
        if (!CommandTools.isAdmin(sessionUserInfo.getMemberType())) {
            return CommonUtil.errorJson("非管理员禁止操作");
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("offSet", (pageNum - 1) * pageRow);
        jsonObject.put("pageSize", pageRow);
        jsonObject.put("phone", phone);
        jsonObject.put("memberType", memberType);
        jsonObject.put("currentTime", DateUtil.getCurrentTime());
        if ("0".equals(expiredType)) {
            jsonObject.put("expiredType", "");
        } else {
            jsonObject.put("expiredType", expiredType);
        }
        int total = wxUserService.countUser(jsonObject);
        return CommonUtil.successPage(pageRow, wxUserService.getUserList(jsonObject), total);
    }

    @PostMapping("/login")
    public JSONObject login(@RequestBody UserInfo userInfo) {
        if (!StringTools.checkPhone(userInfo.getPhone())) {
            return CommonUtil.errorJson("手机号不合法");
        }
        String checkPassword = StringTools.checkPassword(userInfo.getPassword());
        if (!StringTools.isNullOrEmpty(checkPassword)) {
            return CommonUtil.errorJson(checkPassword);
        }
        UserInfo userInfoChild = wxUserService.getUserByPhone(userInfo.getPhone());
        if (userInfoChild == null) {
            return CommonUtil.errorJson("用户不存在");
        } else if (!userInfo.getPassword().equals(userInfoChild.getPassword())) {
            return CommonUtil.errorJson("密码错误");
        } else if (userInfoChild.getEnable() == 0) {
            return CommonUtil.errorJson("用户已被禁用，请联系客服");
        }

        userInfoChild.setPassword("");
        return CommonUtil.successJson(userInfoChild);
    }

    @PostMapping("/masterlogin")
    public JSONObject masterLogin(HttpServletRequest request, HttpServletResponse response, @RequestBody UserInfo userInfo) {
        if (!StringTools.checkPhone(userInfo.getPhone())) {
            return CommonUtil.errorJson("手机号不合法");
        }
        String checkPassword = StringTools.checkPassword(userInfo.getPassword());
        if (!StringTools.isNullOrEmpty(checkPassword)) {
            return CommonUtil.errorJson(checkPassword);
        }
        UserInfo userInfoTemp = wxUserService.getUserByPhone(userInfo.getPhone());
        if (userInfoTemp == null) {
            return CommonUtil.errorJson("用户不存在");
        } else if (!userInfo.getPassword().equals(userInfoTemp.getPassword())) {
            return CommonUtil.errorJson("密码错误");
        } else if (userInfoTemp.getEnable() == 0) {
            return CommonUtil.errorJson("用户已被禁用，请联系客服");
        } else {
            UserInfoDto userInfoDto = new UserInfoDto();
            userInfoDto.setId(userInfoTemp.getId());
            userInfoDto.setPhone(userInfoTemp.getPhone());
            if (userInfoTemp.getChildId() != null) {
                UserInfo userInfoChild = wxUserService.getUser(userInfoTemp.getChildId());
                if (userInfoChild != null) {
                    userInfoDto.setChildPhone(userInfoChild.getPhone());
                }
            }

            //生成token
            String token = "user_" + UUID.randomUUID();
            //从map中获得redis中的key
            String oldToken = UserLogin.get(userInfoTemp.getId());
            //判断map中是否存在该id
            if (StringUtils.isNotBlank(oldToken)) {
                //删除redis中老的值
                jedisDao.delValue(oldToken);
                UserLogin.remove(userInfoTemp.getId());
                log.info("缓存中已存在该用户,删除该用户缓存");
            } else {
                log.info("缓存中未找到该用户");
            }
            //将新的的key保存到map中
            UserLogin.put(userInfoTemp.getId(), token);
            //将信息存入redis
            SessionUserInfo sessionUserInfo = new SessionUserInfo();
            sessionUserInfo.setUserId(userInfoTemp.getId());
            sessionUserInfo.setPhone(userInfoTemp.getPhone());
            jedisDao.setValue(token, JsonUtils.objectToJson(sessionUserInfo));
            jedisDao.setExpireTime(token, Constants.REDIS_EXPIRE_TIME_MONTH);
            //将token放入cookie中
            CookieUtils.setCookie(request, response, KEY, token, 5 * 60, true);
            userInfoDto.setToken(token);
            return CommonUtil.successJson("登录成功", userInfoDto);
        }
    }

    @PostMapping("/register")
    public JSONObject register(@RequestBody UserInfo userInfo) {
        if (!StringTools.checkPhone(userInfo.getPhone())) {
            return CommonUtil.errorJson("手机号不合法");
        }
        String checkPassword = StringTools.checkPassword(userInfo.getPassword());
        if (!StringTools.isNullOrEmpty(checkPassword)) {
            return CommonUtil.errorJson(checkPassword);
        }
        UserInfo userInfoTemp = wxUserService.getUserByPhone(userInfo.getPhone());
        if (userInfoTemp != null) {
            return CommonUtil.errorJson("用户已存在，请勿重复注册");
        }
        userInfo.setMemberType(3);
        userInfo.setCreateTime(new Date());
        userInfo.setUpdateTime(new Date());
        if (wxUserService.insertUser(userInfo)) {
            return CommonUtil.successJson("注册成功");
        } else {
            return CommonUtil.errorJson("注册失败");
        }
    }

    @PutMapping("/bind")
    public JSONObject bindChildPhone(@RequestBody UserInfo userInfo) {
        if (!StringTools.checkPhone(userInfo.getPhone())) {
            return CommonUtil.errorJson("手机号不合法");
        }
        if (!StringTools.checkPhone(userInfo.getChildPhone())) {
            return CommonUtil.errorJson("被绑定人手机号不合法");
        }
        if (userInfo.getPhone().equals(userInfo.getChildPhone())) {
            return CommonUtil.errorJson("不能绑定自己哦");
        }
        UserInfo userInfoMaster = wxUserService.getUserByPhone(userInfo.getPhone());
        if (userInfoMaster == null) {
            return CommonUtil.errorJson("用户不存在");
        } else if (StringUtils.isBlank(userInfoMaster.getActivateCode())) {
            return CommonUtil.errorJson("请先成为会员");
        }
        UserInfo userInfoChild = wxUserService.getUserByPhone(userInfo.getChildPhone());
        if (userInfoChild == null) {
            return CommonUtil.errorJson("用户不存在");
        } else if (wxUserService.getUserByChildId(userInfoChild.getId()) != null) {
            return CommonUtil.errorJson("该用户已被绑定");
        }

        UserInfo userInfoBind = new UserInfo();
        userInfoBind.setId(userInfoMaster.getId());
        userInfoBind.setChildId(userInfoChild.getId());
        userInfoBind.setUpdateTime(new Date());
        if (wxUserService.bindActivateCode(userInfoBind)) {
            return CommonUtil.successJson("绑定成功");
        } else {
            return CommonUtil.errorJson("绑定失败");
        }
    }

    @GetMapping("/{id}")
    public JSONObject getUser(@PathVariable Integer id) {
        return CommonUtil.successJson(wxUserService.getUser(id));
    }

    @PostMapping("/insert")
    public JSONObject insertUser(@RequestBody UserInfo userInfo, HttpServletRequest request) {
        SessionUserInfo sessionUserInfo = (SessionUserInfo) request.getAttribute("users");
        if (sessionUserInfo == null) {
            return CommonUtil.errorJson("管理员不存在");
        }
        if (!CommandTools.isAdmin(sessionUserInfo.getMemberType())) {
            return CommonUtil.errorJson("非管理员禁止操作");
        }
        userInfo.setCreateTime(new Date());
        userInfo.setUpdateTime(new Date());
        if (wxUserService.insertUser(userInfo)) {
            return CommonUtil.successJson("添加成功");
        } else {
            return CommonUtil.errorJson("用户添加失败");
        }
    }

    @PostMapping("/admin")
    public JSONObject insertAdmin(@RequestBody UserInfo userInfo, HttpServletRequest request) {
        SessionUserInfo sessionUserInfo = (SessionUserInfo) request.getAttribute("users");
        if (sessionUserInfo == null) {
            return CommonUtil.errorJson("管理员不存在");
        }
        if (!CommandTools.isAdmin(sessionUserInfo.getMemberType())) {
            return CommonUtil.errorJson("非管理员禁止操作");
        }
        if (!StringTools.checkPhone(userInfo.getPhone())) {
            return CommonUtil.errorJson("手机号不合法");
        }
        UserInfo userInfoTemp = wxUserService.getUserByPhone(userInfo.getPhone());
        if (userInfoTemp != null) {
            return CommonUtil.errorJson("管理员已存在,请勿重复添加");
        }
        userInfo.setMemberType(2);
        userInfo.setCreateTime(new Date());
        userInfo.setUpdateTime(new Date());
        if (wxUserService.insertUser(userInfo)) {
            return CommonUtil.successJson("添加成功");
        } else {
            return CommonUtil.errorJson("用户添加失败");
        }
    }

    @PutMapping("/update")
    public JSONObject updateUser(@RequestBody UserInfo userInfo) {
        if (StringTools.isNullOrEmpty(userInfo.getId())) {
            return CommonUtil.errorJson("用户id不能为空");
        }
        userInfo.setCreateTime(new Date());
        userInfo.setUpdateTime(new Date());
        if (wxUserService.updateUser(userInfo)) {
            return CommonUtil.successJson("修改成功");
        } else {
            return CommonUtil.errorJson("用户添加失败");
        }
    }

    @PutMapping("/{id}/enable/{type}")
    public JSONObject enableUser(@PathVariable Integer id, @PathVariable Integer type, HttpServletRequest request) {
        SessionUserInfo sessionUserInfo = (SessionUserInfo) request.getAttribute("users");
        if (sessionUserInfo == null) {
            return CommonUtil.errorJson("管理员不存在");
        }
        if (!CommandTools.isAdmin(sessionUserInfo.getMemberType())) {
            return CommonUtil.errorJson("非管理员禁止操作");
        }
        UserInfo userInfo = wxUserService.getUser(id);
        if (ObjectUtils.isEmpty(userInfo)) {
            return CommonUtil.errorJson("用户不存在");
        }
        if (type > 0) {
            type = 1;
        } else {
            type = 0;
        }
        userInfo.setEnable(type);
        userInfo.setUpdateTime(new Date());
        if (wxUserService.enableUser(userInfo)) {
            return CommonUtil.successJson("状态修改成功");
        } else {
            return CommonUtil.errorJson("状态修改失败");
        }
    }

    @DeleteMapping("/{id}")
    public JSONObject deleteUser(@PathVariable Integer id, HttpServletRequest request) {
        SessionUserInfo sessionUserInfo = (SessionUserInfo) request.getAttribute("users");
        if (sessionUserInfo == null) {
            return CommonUtil.errorJson("管理员不存在");
        }
        if (!CommandTools.isAdmin(sessionUserInfo.getMemberType())) {
            return CommonUtil.errorJson("非管理员禁止操作");
        }
        UserInfo userInfo = wxUserService.getUser(id);
        if (ObjectUtils.isEmpty(userInfo)) {
            return CommonUtil.errorJson("用户不存在");
        }
        if (userInfo.getMemberType() == 1) {
            return CommonUtil.errorJson("当前用户是超级管理员，禁止删除哦");
        }
        if (wxUserService.deleteUser(id)) {
            return CommonUtil.successJson("删除成功");
        } else {
            return CommonUtil.errorJson("删除失败");
        }
    }

    @DeleteMapping("/users")
    public JSONObject deleteUsers(@RequestBody JSONObject requestJson, HttpServletRequest request) {
        SessionUserInfo sessionUserInfo = (SessionUserInfo) request.getAttribute("users");
        if (sessionUserInfo == null) {
            return CommonUtil.errorJson("管理员不存在");
        }
        if (!CommandTools.isAdmin(sessionUserInfo.getMemberType())) {
            return CommonUtil.errorJson("非管理员禁止操作");
        }
        CommonUtil.hasAllRequired(requestJson, "users");
        String users = requestJson.getString("users");
        String[] usersArr = users.split(",");
        if (com.baomidou.mybatisplus.core.toolkit.ObjectUtils.isEmpty(usersArr)) {
            return CommonUtil.errorJson("删除数据不能为空");
        }
        int len = usersArr.length;
        List<String> list = new ArrayList<>();
        for (int i = 0; i < len; i++) {
            list.add(usersArr[i]);
        }
        if (wxUserService.deleteUsers(list)) {
            return CommonUtil.successJson("删除成功");
        } else {
            return CommonUtil.successJson("删除失败,未找到需要删除的用户");
        }
    }

    /**
     * 绑定激活码
     *
     * @param requestJson
     * @return
     */
    @PutMapping("/{id}/activatecode")
    public JSONObject bindActivateCode(@PathVariable Integer id, @RequestBody JSONObject requestJson) {
        CommonUtil.hasAllRequired(requestJson, "activateCode");
        String activateCode = requestJson.getString("activateCode");
        UserInfo userInfo = wxUserService.getUser(id);
        if (ObjectUtils.isEmpty(userInfo)) {
            return CommonUtil.errorJson("用户不存在");
        }

        ActivationCodePo activationCodePo = activationCodeService.selectByActivateCode(activateCode);
        if (activationCodePo == null) {
            return CommonUtil.errorJson("激活码不存在");
        } else if (StringUtils.isNotBlank(activationCodePo.getPhone())) {
            return CommonUtil.errorJson("该激活码已绑定账号，请更换激活码");
        }
        Date expireDate = userInfo.getExpirationTime();
        Date newExpireDate = null;
        // 未激活过
        if (expireDate == null) {
            expireDate = new Date();
        }
        // 之前激活的已过期
        else if (expireDate.compareTo(new Date()) < 0) {
            expireDate = new Date();
        }

        Integer activateCodeType = activationCodePo.getType();
        // 1天
        if (activateCodeType == 1) {
            newExpireDate = DateUtil.plusDay(expireDate, 1);
        }
        // 1个月
        else if (activateCodeType == 2) {
            newExpireDate = DateUtil.plusMonth(expireDate, 1);
        }
        // 1年
        else if (activateCodeType == 3) {
            newExpireDate = DateUtil.plusYear(expireDate, 1);
        }
        UserInfo userInfoBind = new UserInfo();
        userInfoBind.setId(userInfo.getId());
        userInfoBind.setActivateCode(activateCode);
        userInfoBind.setUpdateTime(new Date());
        userInfoBind.setExpirationTime(newExpireDate);
        if (wxUserService.bindActivateCode(userInfoBind)) {
            ActivationCodePo activationCodePoBind = new ActivationCodePo();
            activationCodePoBind.setCode(activateCode);
            activationCodePoBind.setPhone(userInfo.getPhone());
            activationCodePoBind.setUpdateTime(new Date());
            activationCodePoBind.setActiveTime(new Date());
            activationCodePoBind.setExpirationTime(newExpireDate);
            activationCodeService.bindActivateCodeByPhone(activationCodePoBind);
            return CommonUtil.successJson("激活码绑定成功");
        } else {
            return CommonUtil.errorJson("激活码绑定失败");
        }
    }

    @PostMapping("/devicetoken")
    public JSONObject uploadDeviceToken(@RequestBody UserInfo userInfo) {
        UserInfo userInfoToken = new UserInfo();
        userInfoToken.setId(userInfo.getId());
        userInfoToken.setDeviceToken(userInfo.getDeviceToken());
        wxUserService.uploadDeviceToken(userInfoToken);
        return CommonUtil.successJson("更新成功");
    }
}
